const path = require("path");
const useragent = require("useragent");

const IP = {
  /**
   * 获取ip地址
   * @param {请求体} req
   * @returns 返回ip地址
   */
  getIpAddress(req) {
    /* 
        X-Real-IP: Nginx 服务代理, 优先使用 Nginx 作代理, 因此优先获取这个
        X-Forwarded-For 经过 HTTP 代理或 负载均衡服务器时会添加该项
	    X-Forwarded-For 格式: client1,proxy1,proxy2
	    一般情况下，第一个 IP 为客户端真实 IP，后面的为经过的代理服务器 IP
        Pdoxy-Client-IP: Apache 服务代理
        WL-Proxy-Client-IP: Weblogic 服务代理
        RemoteAddr: 发出请求的远程主机的 IP 地址 (经过代理会设置为代理机器的 IP)
        检测到是本机 IP, 读取其局域网 IP 地址
        req.ip = ::ffff:127.0.0.1
        req.connection.remoteAddress = ::ffff:127.0.0.1
        req.socket.remoteAddress = ::ffff:127.0.0.1

        */
    let ipAddress =
      req.get("X-Real-IP") ||
      req.get("X-Forwarded-For") ||
      req.get("Proxy-Client-IP") ||
      req.get("WL-Proxy-Client-IP") ||
      req.ip ||
      req.connection.remoteAddress ||
      req.socket.remoteAddress ||
      req.connection.socket.remoteAddress;

    if (
      ipAddress.startsWith("::ffff:127.0.0.1") ||
      ipAddress.startsWith("127.0.0.1")
    ) {
      try {
        const ip = this.getExternalIP();
        //如果获取不到外网IP则使用本地IP
        ipAddress = ip ? ip.toString() : ipAddress;
      } catch (error) {
        console.error("GetIpAddress, externalIP, err: ", error);
      }
    }

    if (ipAddress && ipAddress.length > 15 && ipAddress.indexOf(",") > 0) {
      // 处理代理情况，截取第一个地址
      ipAddress = ipAddress.split(",")[0];
    }

    return ipAddress;
  },

  /**
   *根据ip地址获取ip属地信息
   * @param {ip地址 127.0.0.0.1} ipAddress
   * @returns 返回ip地址信息 例如：0|0|0|内网IP|内网IP
   */
  async getIpSource(ipAddress) {
    const dbPath = path.join(__dirname, "../assets/ip2region.xdb"); // IP 数据库文件路径
    const Searcher = require("@/ip2region-master/binding/nodejs/index"); //引入ip解析的文件
    try {
      // 同步读取vectorIndex 二进制数据
      const vectorIndex = Searcher.loadVectorIndexFromFile(dbPath);
      // 创建searcher对象
      const searcher = Searcher.newWithVectorIndex(dbPath, vectorIndex);
      // data: {region: '中国|0|江苏省|苏州市|电信', ioCount: 2, took: 0.402874}
      let data = await searcher.search(ipAddress); //传入IP地址解析
      // console.log(data);本地结果 { region: '0|0|0|内网IP|内网IP', ioCount: 2, took: 7620.8 }
      // ip属地格式预处理
      //   data = this.getIpSourceSimpleIdle(data.region); 测试代码查看是否可以获取简易版ip信息

      // 返回结果
      return JSON.stringify({
        data: data.region,
      });
    } catch (error) {
      console.log("获取ip详情地址失败", err);
      return JSON.stringify({
        data: {},
      });
    }
  },
  /**
   *获取简易版的ip地址信息
   * @param {ip地址 127.0.0.0.1} ipAddress
   * @returns 返回简易的ip地址信息 ip内网 或者 完整的地址信息
   */
  async getIpSourceSimpleIdle(ipAddress) {
    //获取完整的ip地址信息 0|0|0|内网IP|内网IP
    let data = await this.getIpSource(ipAddress);
    let { data: region } = JSON.parse(data);
    //如果是本地直接返回
    if (region.includes("内网IP")) {
      return "内网IP";
    }
    // 返回体
    let adrList = {
      country: "",
      province: "",
      city: "",
      type: "",
    };
    // region = "中国|0|江苏省|苏州市|电信"; 测试代码
    // 根据|分割成数组，然后依次赋值
    // region | 划分一个意思[ '0', '0', '0', '内网IP', '内网IP' ]：如果是服务器就是如下：中国|0|江苏省|苏州市|电信
    let list = region.split("|");
    adrList.country = list[0] !== "0" ? list[0] : "";
    adrList.province = list[2] !== "0" ? list[2] : "";
    adrList.city = list[3] !== "0" ? list[3] : "";
    adrList.type = list[4] !== "0" ? list[4] : "";
    // 返回结果，示例：{ country: '中国', province: '江苏省', city: '徐州市', type: '移动' }
    return adrList;
  },

  /**
   * 获取用户代理信息（User Agent）
   * @param {*} req
   * @returns
   */
  getUserAgent(req) {
    return useragent.parse(req.get("User-Agent"));
  },

  /**
   * 如果是本地情况，查看是否能够获取ip信息
   * @returns
   */
  getExternalIP() {
    const interfaces = require("os").networkInterfaces(); //获取计算机的网络接口信息
    //#region
    /*
    interface {
  'VMware Network Adapter VMnet1': [
    {
      address: 'fe80::a536:6b97:4fe4:f929',
      netmask: 'ffff:ffff:ffff:ffff::',
      family: 'IPv6',
      mac: '00:50:56:c0:00:01',
      internal: false,
      cidr: 'fe80::a536:6b97:4fe4:f929/64',
      scopeid: 21
    },
    {
      address: '192.168.153.1',
      netmask: '255.255.255.0',
      family: 'IPv4',
      mac: '00:50:56:c0:00:01',
      internal: false,
      cidr: '192.168.153.1/24'
    }
  ],
  'VMware Network Adapter VMnet8': [
    {
      address: 'fe80::5fc5:4fab:70d5:fb79',
      netmask: 'ffff:ffff:ffff:ffff::',
      family: 'IPv6',
      mac: '00:50:56:c0:00:08',
      internal: false,
      cidr: 'fe80::5fc5:4fab:70d5:fb79/64',
      scopeid: 11
    },
    {
      address: '192.168.204.1',
      netmask: '255.255.255.0',
      family: 'IPv4',
      mac: '00:50:56:c0:00:08',
      internal: false,
      cidr: '192.168.204.1/24'
    }
  ],
  WLAN: [
    {
      address: '192.168.10.5',
      netmask: '255.255.255.0',
      family: 'IPv4',
      mac: '90:78:41:42:55:36',
      internal: false,
      cidr: '192.168.10.5/24'
    }
  ],
  'Loopback Pseudo-Interface 1': [
    {
      address: '::1',
      netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
      family: 'IPv6',
      mac: '00:00:00:00:00:00',
      internal: true,
      cidr: '::1/128',
      scopeid: 0
    },
    {
      address: '127.0.0.1',
      netmask: '255.0.0.0',
      family: 'IPv4',
      mac: '00:00:00:00:00:00',
      internal: true,
      cidr: '127.0.0.1/8'
    }
  ]
}
    */
    //#endregion
    //   遍历每个网络接口，对于每个接口，遍历它的别名。上面注释的为遍历的初始数据
    for (const ifaceName in interfaces) {
      const iface = interfaces[ifaceName];
      for (const alias of iface) {
        // 获取非 127.0.0.1 的局域网 IP
        // internal <boolean> true 如果网络接口是环回接口或不可远程访问的类似接口； 否则 false
        if (
          alias.family === "IPv4" &&
          alias.address !== "127.0.0.1" &&
          !alias.internal
        ) {
          return alias.address;
        }
      }
    }
    throw new Error("Connected to the network");
  },
};

module.exports = { IP };
